/**
 * StAXUtilities.java
 * Nov 18, 2013
 * Copyright: phongtdse60732@fpt.edu.vn
 */
package XMLUtilities;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;

import VMO.DishVMO;
import VMO.MealVMO;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

/**
 * @author trandophong
 * @version 1.0
 */
public class StAXUtilities {
	private static XMLStreamReader createStAXCursor(String filePath)
			throws XMLStreamException, FileNotFoundException {
		XMLInputFactory xif = XMLInputFactory.newInstance();
		InputStream is = new FileInputStream(filePath);
		XMLStreamReader xsr = xif.createXMLStreamReader(is);
		return xsr;
	}

	private static String getTextNodeOfElement(XMLStreamReader xsr,
			String tagName) {
		String result = "";
		while (!xsr.getLocalName().equals(tagName)) {
			try {
				xsr.nextTag(); // start element
				xsr.next(); // value
				if (xsr.hasText()) { // has text --> get text. Else there
					result = xsr.getText();
					xsr.nextTag(); // end element
				}
			} catch (XMLStreamException ex) {
			}
		}
		return result;
	}

	public static ArrayList<MealVMO> findDishList(String xmlFilePath,
			String menuId, String strMealOrderMin, String strMealOrderMax) {
		ArrayList<MealVMO> mealList = new ArrayList<MealVMO>();
		XMLStreamReader xsr = null;
		int min = Integer.parseInt(strMealOrderMin);
		int max = Integer.parseInt(strMealOrderMax);
		try {
			xsr = createStAXCursor(xmlFilePath);
			while (xsr.hasNext()) {
				int cursor = xsr.next();
				if (cursor == XMLStreamConstants.START_ELEMENT) {
					if (xsr.getLocalName().equals("PlanInMeal")) {

						String s1 = getTextNodeOfElement(xsr, "menuId").trim();
						String s2 = getTextNodeOfElement(xsr, "mealOrder")
								.trim();
						int intS2 = Integer.parseInt(s2);
						if (s1.equals(menuId) && intS2 <= max && intS2 >= min) {
							MealVMO meal = new MealVMO();
							ArrayList<DishVMO> dishList = new ArrayList<DishVMO>();
							while (!xsr.getLocalName().equals("dishList")
									|| cursor != XMLStreamConstants.END_ELEMENT) {
								cursor = xsr.next();
								cursor = xsr.next();
								if (cursor == XMLStreamConstants.START_ELEMENT
										&& xsr.getLocalName().equals("Dish")) {
									String name = getTextNodeOfElement(xsr,
											"name").trim();
									String calo = getTextNodeOfElement(xsr,
											"calo").trim();
									String cooking = getTextNodeOfElement(xsr,
											"cookingName").trim();
									String des = getTextNodeOfElement(xsr,
											"description").trim();
									String imgPath = getTextNodeOfElement(xsr,
											"imgPath").trim();
									DishVMO dish = new DishVMO(name, calo,
											cooking, des, imgPath);
									dishList.add(dish);
								}
							}
							meal.setDishList(dishList);
							mealList.add(meal);
						}

					}
				}
			}
			return mealList;
		} catch (Exception ex) {
		}
		return null;
	}

	public static ArrayList<DishVMO> findDishInRecipe(String xmlFilePath,
			int recipeId) {
		String recipeId_str = String.valueOf(recipeId);
		ArrayList<DishVMO> dishListVMO = new ArrayList<DishVMO>();
		XMLInputFactory xif = XMLInputFactory.newInstance();
		FileReader fileReader;
		try {
			fileReader = new FileReader(new File(xmlFilePath));
			XMLEventReader reader = xif.createXMLEventReader(fileReader);
			while (reader.hasNext()) {
				XMLEvent event = reader.nextEvent();
				if (event.isStartElement()) {
					StartElement element = (StartElement) event;
					if (element.getName().getLocalPart().equals("RecipeDetail")) {
						Iterator iterator = element.getAttributes();
						Attribute attribute = (Attribute) iterator.next();
						// found RecipeDetail
						if (attribute.getValue().equals(recipeId_str)) {
							while (reader.hasNext()) {
								event = reader.nextEvent();
								if (event.isStartElement()) {
									element = (StartElement) event;
									// found a Dish
									if (element.getName().getLocalPart()
											.equals("Dish")) {
										DishVMO dishVMO = new DishVMO();
										String currentElementName = "";
										while (reader.hasNext()) {
											event = reader.nextEvent();
											if (event.isStartElement()) {
												element = (StartElement) event;
												if (element.getName()
														.getLocalPart()
														.equals("name")) {
													currentElementName = "name";
												} else if (element.getName()
														.getLocalPart()
														.equals("calo")) {
													currentElementName = "calo";
												} else if (element.getName()
														.getLocalPart()
														.equals("cookingName")) {
													currentElementName = "cookingName";
												} else if (element.getName()
														.getLocalPart()
														.equals("description")) {
													currentElementName = "description";
												} else if (element.getName()
														.getLocalPart()
														.equals("imgPath")) {
													currentElementName = "imgPath";
												}
											} else if (event.isCharacters()) {
												Characters chars = (Characters) event;
												if (!chars.isWhiteSpace()) {
													if (currentElementName
															.equals("name")) {
														dishVMO.setName(chars
																.getData());
													} else if (currentElementName
															.equals("calo")) {
														dishVMO.setCalo(chars
																.getData());
													} else if (currentElementName
															.equals("cookingName")) {
														dishVMO.setCooking(chars
																.getData());
													} else if (currentElementName
															.equals("description")) {
														dishVMO.setDescription(chars
																.getData());
													} else if (currentElementName
															.equals("imgPath")) {
														dishVMO.setImgPath(chars
																.getData());
													}
												}
											} else if (event.isEndElement()) {
												EndElement endElement = (EndElement) event;
												if (endElement.getName()
														.getLocalPart()
														.equals("Dish")) {
													dishListVMO.add(dishVMO);
													break;
												}
											}
										}
									}
								} else if (event.isEndElement()) {
									EndElement endElement = (EndElement) event;
									if (endElement.getName().getLocalPart()
											.equals("DishList")) {
										break;
									}
								}
							}
							break;
						}
					}
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (XMLStreamException e) {
			e.printStackTrace();
		}
		return dishListVMO;
	}
}